/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.risk.service.impl;


import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.web.Util;
import com.koron.hazardsource.mapper.IndicationItemsMapper;
import com.koron.risk.domain.PointManagement;
import com.koron.risk.mapper.AnalysisMapper;
import com.koron.risk.mapper.PointManagementMapper;
import com.koron.risk.service.api.GridNodeService;
import com.koron.risk.service.api.PointManagementService;
import com.koron.risk.util.BusinessCode;
import com.koron.system.domain.DictData;
import com.koron.system.domain.DictType;
import com.koron.system.service.api.DictDataService;
import com.koron.system.service.api.DictTypeService;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PointManagementServiceImpl implements PointManagementService {

    private final static Logger logger= LoggerFactory.getLogger(PointManagementServiceImpl.class);
    @Autowired
    private Util util;

    @Autowired
    private GridNodeService nodeService;

    @Autowired
    private DictDataService dataService;

    @Autowired
    private DictTypeService dictTypeService;

    private Map<String, String> mapDict = new HashMap<>();

    private final String corp = "776B361BFFAC4F00BBF459CD1303A8B2";

    @Override
    public MessageBean<?> sava(StaffBean user, PointManagement point) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, void.class);
        SessionFactory factory = new SessionFactory();
        try {
            if (StringUtils.isEmpty(point.getPointX()) || StringUtils.isEmpty(point.getPointY())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("坐标不能为空");
                return msg;
            }
            if (StringUtils.isEmpty(point.getId())) {
                point.setId(DefaultIdGenerator.getInstance().generateLongId());
                point.setAddUser(user.getCode());
                point.setAddUserName(user.getName());
                point.setAddTime(point.getUpdateTime());
                Integer insert = factory.getMapper(PointManagementMapper.class).insert(point);
                if (insert <= 0) {
                    factory.close(false);
                    msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
                    return msg;
                }
                factory.close();
                return msg;
            } else {
                PointManagement entity = factory.getMapper(PointManagementMapper.class).queryOne(point.getId());
                if (null == entity) {
                    msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                    msg.setDescription("您修改的坐标信息不存在");
                    return msg;
                }
                Integer update = factory.getMapper(PointManagementMapper.class).update(point);
                if (update <= 0) {
                    factory.close(false);
                    msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
                    return msg;
                }
                factory.close();
                return msg;
            }
        } catch (Exception e) {
            if (null != factory)
                factory.close(false);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    @Override
    public MessageBean<PointManagement> details(StaffBean user, String id) {
        MessageBean<PointManagement> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, PointManagement.class);
        try (SessionFactory factory = new SessionFactory()) {
            List<Map> list = new ArrayList<>();
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("缺少必要参数");
                return msg;
            }
            PointManagement point = factory.getMapper(PointManagementMapper.class).queryOne(id);
            if (null == point) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("坐标信息不存在");
                return msg;
            }
            String corpCode = point.getCorpCode();
            //查询当前部门下的所有网格（包括网格和部门）,不包含自己本身
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (codeList == null) {
                codeList = new ArrayList<>();
            }
            codeList.add(corpCode);
            // 获取隐患统计数据
            if (null == mapDict || mapDict.isEmpty()) {
                setMap();
            }
            Map<String, Object> dangerAnalysis = factory.getMapper(AnalysisMapper.class).queryCountDangerByGrid(mapDict.get("nomarlDangerCount"), mapDict.get("importantDangerCont"), mapDict.get("managerDangetCount"),
                    mapDict.get("deviceDangerCount"), mapDict.get("meterialDangerCount"), mapDict.get("personDangerCount"), mapDict.get("goodsDangerCount"),
                    mapDict.get("enviropmentDangerCount"), codeList);
            Map<String, Object> dangerAnalysis1 = factory.getMapper(AnalysisMapper.class).queryCountDangerPrecautionByGrid(mapDict.get("unreformCount"), mapDict.get("alreadyReformCount1"), mapDict.get("reformingCount"),
                    mapDict.get("refuseReformCount"), codeList);
            // 如果未找到数据，设为0
            if (null == dangerAnalysis) {
                dangerAnalysis.put("nomarlDangerCount", 0);
                dangerAnalysis.put("importantDangerCount", 0);
                dangerAnalysis.put("managerDangerCount", 0);
                dangerAnalysis.put("deviceAndMeterialDangerCount", 0);
                dangerAnalysis.put("personDangerCount", 0);
                dangerAnalysis.put("goodsDangerCount", 0);
                dangerAnalysis.put("enviropmentDangerCount", 0);
                dangerAnalysis.put("alreadyReformCount", 0);
                dangerAnalysis.put("reformingCount", 0);
                dangerAnalysis.put("unreformCount", 0);
                dangerAnalysis.put("reformRate", new BigDecimal(0));
            }
            if (null != dangerAnalysis1) {
                dangerAnalysis.put("alreadyReformCount", dangerAnalysis1.get("alreadyReformCount"));
                dangerAnalysis.put("reformingCount", dangerAnalysis1.get("reformingCount"));
                dangerAnalysis.put("unreformCount", dangerAnalysis1.get("unreformCount"));
                Integer total = Integer.valueOf(dangerAnalysis1.get("unreformCount").toString()) + Integer.valueOf(dangerAnalysis1.get("reformingCount").toString()) + Integer.valueOf(dangerAnalysis1.get("alreadyReformCount").toString());
                BigDecimal totalValue = new BigDecimal(total);
                BigDecimal rate = total == 0 ? new BigDecimal(0) : new BigDecimal(Integer.valueOf(dangerAnalysis1.get("alreadyReformCount").toString())).divide(totalValue, 4, BigDecimal.ROUND_HALF_UP);
                dangerAnalysis.put("reformRate", rate);
            }
            point.setDangerAnalysis(dangerAnalysis);
            // 获取危险源统计数据
            //查风险统计
            Map<String, Integer> analysis = factory.getMapper(AnalysisMapper.class).queryCountRiskHazardSourceByGrid(codeList);
            //查重大危险源数量
            Map<String, Integer> analysis1 = factory.getMapper(AnalysisMapper.class).queryCountHazradByGrid(mapDict.get("majorHazardSource"), codeList);
            if (null == analysis) {
                analysis.put("normalRisk", 0);
                analysis.put("majorRisk", 0);
                analysis.put("greaterRisk", 0);
                analysis.put("lowRisk", 0);
                analysis.put("majorHazardSource", 0);
            }
            if (analysis1 != null) {
                analysis.put("majorHazardSource", analysis1.get("majorHazardSource"));
            }
            point.setLocalHazarsSourceAnalysis(analysis);
            // 获取危险作业统计数据
            Map dangerousOperationAnalysis = factory.getMapper(AnalysisMapper.class).getDangerousOperationAnalysis(codeList);
            if (null == dangerousOperationAnalysis) {
                dangerousOperationAnalysis.put("applyCount", 0);
                dangerousOperationAnalysis.put("operationCount", 0);
                dangerousOperationAnalysis.put("completeCount", 0);
                dangerousOperationAnalysis.put("totalCount", 0);
            }
            point.setDangerousOperationAnalysis(dangerousOperationAnalysis);
            msg.setData(point);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        }
    }

    @Override
    public MessageBean<Integer> delete(String id) {
        MessageBean<Integer> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, Integer.class);
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("缺少必要参数");
                return msg;
            }
            PointManagement point = factory.getMapper(PointManagementMapper.class).queryOne(id);
            if (null == point) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("坐标信息不存在");
                return msg;
            }
            Integer delete = factory.getMapper(PointManagementMapper.class).delete(id);
            if (delete <= 0) {
                factory.close(false);
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
                return msg;
            }
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean> list(StaffBean user, String corpCode, String name, String title, String type, Integer operationType, Integer page, Integer pageSize) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, DataBean.class);
        try (SessionFactory factory = new SessionFactory()) {
            // 获取当前登录人所属单位
            DepartmentTreeBean dept = null;
            List<DepartmentTreeBean> deptList = null;
            List<String> corpCodeList = new ArrayList<>();
            MessageBean<?> corpMsg = util.corp(user.getCode());
            if (corpMsg.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                dept = (DepartmentTreeBean) corpMsg.getData();
            }
            if (null != dept) {
                //获取单位下所有的下属公司及部门
                MessageBean<?> depttreeMsg = util.depttree(dept.getDepartmentCode(), 1);
                if (depttreeMsg.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                    deptList = (List<DepartmentTreeBean>) depttreeMsg.getData();
                }
            }
            if (null != deptList) {
                List<String> collect = deptList.stream().map(departmentTreeBean -> departmentTreeBean.getDepartmentCode()).collect(Collectors.toList());
                corpCodeList.addAll(collect);
            }
            Integer start = null;
            if (null != page && page > 0 && null != pageSize && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            List<PointManagement> list = factory.getMapper(PointManagementMapper.class).getList(corpCode, name, title, type, operationType, start, pageSize);
            //获取属于当前公司下的子公司或部门的坐标点
            List<PointManagement> result = list.stream().filter(pointManagement -> corpCodeList.contains(pointManagement.getCorpCode())).collect(Collectors.toList());
//            Integer count = factory.getMapper(PointManagementMapper.class).getCount(corpCode, name, title, type, operationType);
            Integer count = result.size();
            DataBean dataBean = new DataBean();
//            dataBean.setList(list);
            dataBean.setList(result);
            dataBean.setTotalNumber(count);
            if (null != page && page > 0 && null != pageSize && pageSize > 0) {
                dataBean.setTotalPage(count > pageSize ? count % pageSize == 0 ? count / pageSize : count / pageSize + 1 : 1);
                dataBean.setPageNo(page);
                dataBean.setPageSize(pageSize);
            } else {
                dataBean.setTotalPage(1);
                dataBean.setPageNo(1);
                dataBean.setPageSize(count);
            }
            msg.setData(dataBean);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        }
    }

    /**
     * 获取单位下所有坐标点
     *
     * @param user
     * @param corpCode
     * @return
     */
    @Override
    public MessageBean<List> getAll(StaffBean user, String corpCode) {
        MessageBean<List> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, List.class);
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            List<DepartmentTreeBean> deptList = null;
            MessageBean<?> depttreeMsg = null;
            if (corp.equals(corpCode)) {
                //获取单位的下属公司,不包含子集部门
                depttreeMsg = util.depttree(corpCode, 0);
            } else {
                //获取单位的下属公司,包含子集部门
                depttreeMsg = util.depttree(corpCode, 1);
            }
            if (null != depttreeMsg && depttreeMsg.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                deptList = (List<DepartmentTreeBean>) depttreeMsg.getData();
            }
            if (null != deptList && deptList.size() > 0) {
                String finalCorpCode = corpCode;
                deptList = deptList.stream().filter(bean -> (bean.getDeptType() & 16) == 16).collect(Collectors.toList());
            }
            // 获取所有坐标点
            List<PointManagement> list = factory.getMapper(PointManagementMapper.class).getAll();
            List<String> pointCorpCodeList = list.stream().map(PointManagement::getCorpCode).collect(Collectors.toList());
            Map<String, PointManagement> pointManagementMap = list.stream().collect(Collectors.toMap(PointManagement::getCorpCode, point -> point, (o1, o2) -> o2));
            List<PointManagement> result = new ArrayList<>();
            if (null != deptList && deptList.size() > 0) {
                result = deptList.stream().filter(corp -> pointCorpCodeList.contains(corp.getDepartmentCode())).map(corp -> {
                    PointManagement pointManagement = pointManagementMap.get(corp.getDepartmentCode());
                    pointManagement.setName(corp.getName());
                    return pointManagement;
                }).collect(Collectors.toList());
            }
            //获取属于当前公司下的子公司或部门的坐标点
//            List<PointManagement> result = list.stream().filter(pointManagement -> corpCodeList.contains(pointManagement.getCorpCode())).collect(Collectors.toList());
            if (null != result && result.size() > 1) {
                for (PointManagement pointManagement : result) {
                    if (corpCode.equals(pointManagement.getCorpCode())) {
                        pointManagement.setChild(1);
                    }
                }
            }
            result.forEach(pointManagement -> {
                // 获取最新的三个作业票信息
                getDangerousOperation(factory, pointManagement);
            });
            msg.setData(result);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        }
    }

    private void getDangerousOperation(SessionFactory factory, PointManagement pointManagement) {
        List<String> codeList = nodeService.getChildCodeList(pointManagement.getCorpCode());
        if (null == codeList) {
            codeList = new ArrayList<>();
        }
        if (!codeList.contains(pointManagement.getCorpCode())) {
            codeList.add(pointManagement.getCorpCode());
        }
        // 获取最新的三条危险作业数据
        List<String> dangerousOperation = factory.getMapper(AnalysisMapper.class).getDangerousOperation(codeList);
        pointManagement.setDangerousOperation(dangerousOperation);
    }

    /**
     * 获取公司隐患整改情况
     *
     * @param factory
     * @param corpCode
     * @return
     */
    @Override
    public MessageBean<Map> dangerAnalysis(SessionFactory factory, String corpCode) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            // 获取隐患统计数据
            if (null == mapDict || mapDict.isEmpty()) {
                setMap();
            }
            AnalysisMapper mapper = factory.getMapper(AnalysisMapper.class);
            Map dangerMap = mapper.queryCountDangerPrecautionByGrid(mapDict.get("unreformCount"),
                    mapDict.get("alreadyReformCount1"), mapDict.get("reformingCount"), mapDict.get("refuseReformCount"), codeList);
            calcRate(dangerMap);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("查询隐患统计数据成功");
            msg.setData(dangerMap);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询隐患统计数据失败");
            return msg;
        }
    }

    /**
     * 获取公司隐患整改情况,当前年和当前月
     *
     * @param factory
     * @param corpCode
     * @return
     */
    @Override
    public MessageBean<Map> dangerAnalysisWithDate(SessionFactory factory, String corpCode) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            //查询当前公司下的所有网格（包括网格和部门）
//            List<String> codeList = nodeService.getChildCodeList(corpCode);

            String codeList = util.getDeptCodes(corpCode);
            // 获取隐患统计数据
            if (null == mapDict || mapDict.isEmpty()) {
                setMap();
            }
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            calendar.set(year, 0, 1, 0, 0, 0);
            // 设置开始年和结束年
            Date startYear = calendar.getTime();
            calendar.add(Calendar.YEAR, 1);
            Date stopYear = calendar.getTime();
            // 获取当前年的隐患统计数据
//            Map<String, Object> currentMapYear = factory.getMapper(AnalysisMapper.class).queryCountDangerByYear(mapDict.get("unreformCount"),
//                    mapDict.get("alreadyReformCount1"), mapDict.get("reformingCount"), mapDict.get("refuseReformCount"), startYear, stopYear, codeList);
            Map<String, Object> currentMapYear = factory.getMapper(AnalysisMapper.class).queryDangerAnalysisWithDate(startYear, stopYear, codeList);
            Map yearMap = calcRateWithDate(currentMapYear);
            // 设置开始月和结束月
            calendar.set(year, month, 1, 0, 0, 0);
            Date startMouth = calendar.getTime();
            calendar.add(Calendar.MONTH, 1);
            Date stopMouth = calendar.getTime();
            // 获取当前月的隐患统计数据
//            Map<String, Object> currentMouth = factory.getMapper(AnalysisMapper.class).queryCountDangerByYear(mapDict.get("unreformCount"),
//                    mapDict.get("alreadyReformCount1"), mapDict.get("reformingCount"), mapDict.get("refuseReformCount"), startMouth, stopMouth, codeList);
            Map<String, Object> currentMouth = factory.getMapper(AnalysisMapper.class).queryDangerAnalysisWithDate(startMouth, stopMouth, codeList);
            Map mountMap = calcRateWithDate(currentMouth);
            Map map = new HashMap();
            map.put("currentYear", yearMap);
            map.put("currentMouth", mountMap);
            msg.setData(map);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询隐患统计数据失败");
            return msg;
        }
    }

    /**
     * 计算总数及完成率
     *
     * @param map
     */
    public void calcRate(Map map) {
        if (null != map) {
            //只统计整改中和整改完成的数据
            Integer total = Integer.valueOf(map.get("reformingCount").toString()) + Integer.valueOf(map.get("alreadyReformCount").toString());
            map.put("totalCount", total);
            BigDecimal totalValue = new BigDecimal(total);
            BigDecimal rate = total == 0 ? new BigDecimal(0) : new BigDecimal(Integer.valueOf(map.get("alreadyReformCount").toString())).divide(totalValue, 4, BigDecimal.ROUND_HALF_UP);
            map.put("reformRate", rate);
        }
    }

    public Map calcRateWithDate(Map map) {
        Map result = new HashMap();
        if (null != map) {
            //未整改和整改中的都算做是未整改
            Integer total = Integer.valueOf(map.get("reformingCount").toString()) + Integer.valueOf(map.get("alreadyReformCount").toString()) + Integer.valueOf(map.get("unreformCount").toString());
            Integer unreformCount = Integer.valueOf(map.get("reformingCount").toString()) + Integer.valueOf(map.get("unreformCount").toString());
            result.put("unreformCount", unreformCount);
            result.put("alreadyReformCount", map.get("alreadyReformCount"));
            result.put("totalCount", total);
            if (total != 0) {
                BigDecimal rate = new BigDecimal(Integer.valueOf(map.get("alreadyReformCount").toString())).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP);
                // 将完成率转换成百分比
                NumberFormat percent = NumberFormat.getPercentInstance();
                percent.setMaximumFractionDigits(0);
                result.put("reformRate", percent.format(rate));
            } else {
                result.put("reformRate", "100%");
            }
        }
        return result;
    }

    /**
     * 获取公司年度各月安全检查数量
     *
     * @param factory
     * @param corpCode
     * @param year
     * @return
     */
    @Override
    public MessageBean<List<Map>> safetyCheckAnalysis(SessionFactory factory, String corpCode, Integer year) {
        MessageBean<List<Map>> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            List<Map> list = new ArrayList<>();
            // 判断是否输入了年份，没有默认当年
            if (null == year) {
                LocalDateTime dateTime = LocalDateTime.now();
                year = dateTime.getYear();
            }
            // 按月获取统计年份的所有安全检查数量
            Map<String, Long> safetyMap = factory.getMapper(PointManagementMapper.class).getSafetyCheckAnalysis(codeList, year + "-");
            // 按月获取统计年份的所有物质检查数量
            Map<String, Long> materialMap = factory.getMapper(PointManagementMapper.class).getMaterialCheckAnalysis(codeList, year + "-");
            // 按月获取统计年份的所有设备检查数量
            Map<String, Long> deviceMap = factory.getMapper(PointManagementMapper.class).getDeviceCheckAnalysis(codeList, year + "-");
            // 计算各月的安全检查总数
            Map totalMap = calcTotalNum(safetyMap, materialMap, deviceMap);
//            Map<String,Map>mapMap = new HashMap<>();
//            mapMap.put("total",totalMap);
//            mapMap.put("safety",safetyMap);
//            mapMap.put("device",deviceMap);
//            mapMap.put("material",materialMap);
//            list.add(mapMap);
            list.add(totalMap);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("查询安全检查统计数据成功");
            msg.setData(list);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询安全检查统计数据失败");
            return msg;
        }
    }


    private Map calcTotalNum(Map<String, Long> safetyMap, Map<String, Long> materialMap, Map<String, Long> deviceMap) {
        Map map = new HashMap();
        // 将安全检查，物质检查，设备检查每月统计数量相加，作为当月总的安全检查数量
        if (null != safetyMap && null != materialMap && null != deviceMap) {
            map.put("totalJanuary", safetyMap.get("safeJanuaryCount") + materialMap.get("materialJanuaryCount") + deviceMap.get("deviceJanuaryCount"));
            map.put("totalFebruary", safetyMap.get("safeFebruaryCount") + materialMap.get("materialFebruaryCount") + deviceMap.get("deviceFebruaryCount"));
            map.put("totalMarch", safetyMap.get("safeMarchCount") + materialMap.get("materialMarchCount") + deviceMap.get("deviceMarchCount"));
            map.put("totalApril", safetyMap.get("safeAprilCount") + materialMap.get("materialAprilCount") + deviceMap.get("deviceAprilCount"));
            map.put("totalMay", safetyMap.get("safeMayCount") + materialMap.get("materialMayCount") + deviceMap.get("deviceMayCount"));
            map.put("totalJune", safetyMap.get("safeJuneCount") + materialMap.get("materialJuneCount") + deviceMap.get("deviceJuneCount"));
            map.put("totalJuly", safetyMap.get("safeJulyCount") + materialMap.get("materialJulyCount") + deviceMap.get("deviceJulyCount"));
            map.put("totalAugust", safetyMap.get("safeAugustCount") + materialMap.get("materialAugustCount") + deviceMap.get("deviceAugustCount"));
            map.put("totalSeptember", safetyMap.get("safeSeptemberCount") + materialMap.get("materialSeptemberCount") + deviceMap.get("deviceSeptemberCount"));
            map.put("totalOctober", safetyMap.get("safeOctoberCount") + materialMap.get("materialOctoberCount") + deviceMap.get("deviceOctoberCount"));
            map.put("totalNovember", safetyMap.get("safeNovemberCount") + materialMap.get("materialNovemberCount") + deviceMap.get("deviceNovemberCount"));
            map.put("totalDecember", safetyMap.get("safeDecemberCount") + materialMap.get("materialDecemberCount") + deviceMap.get("deviceDecemberCount"));
        }
        return map;
    }

    /**
     * 获取公司年度危险作业统计数量
     *
     * @param factory
     * @param corpCode
     * @param year
     * @return
     */
    @Override
    public MessageBean<Map> dangerousOperationAnalysis(SessionFactory factory, String corpCode, String operationTicketType, Integer year) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            // 判断是否输入了年份，没有默认当年
            if (null == year) {
                LocalDateTime dateTime = LocalDateTime.now();
                year = dateTime.getYear();
            }
            Map operationAnalysis = factory.getMapper(PointManagementMapper.class).getDangerousOperationAnalysis(codeList, operationTicketType, year + "-");
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("查询危险作业统计数据成功");
            msg.setData(operationAnalysis);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询危险作业统计数据失败");
            return msg;
        }

    }

    @Override
    public MessageBean<Map> safetyDrillAnalysis(SessionFactory factory, String corpCode, String time, Integer year, Integer mouth) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            Calendar calendar = Calendar.getInstance();
            // 判断是否输入了年-月，没有默认当年当月
            if (StringUtils.isEmpty(time)) {
                year = calendar.get(Calendar.YEAR);
                mouth = calendar.get(Calendar.MONTH) + 1;
            } else {
                year = Integer.valueOf(time.split("-")[0]);
                mouth = Integer.valueOf(time.split("-")[1]);
            }
            calendar.set(year, mouth - 1, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.MONTH, 1);
            Date stopDate = calendar.getTime();
            // 获取演练场次和参与人数
            Map drillAnalysis = factory.getMapper(AnalysisMapper.class).getDrillAnalysis(startDate, stopDate, codeList);
            // 获取演练类型
            List<Map> drillTypeAnalysis = factory.getMapper(AnalysisMapper.class).getDrillTypeAnalysis(startDate, stopDate, codeList);
            List<String> drillType = drillTypeAnalysis.stream().map(map -> map.get("drillType").toString()).collect(Collectors.toList());
            // 获取演练类型字典数据
            MessageBean<List<DictType>> dictDrillTypes = dictTypeService.getDictTypesAndDictDatas("演练类型");
            // 类型字典id
            List<String> dirllTypeList = dictDrillTypes.getData().get(0).getDataList().stream().map(dictData -> dictData.getId()).collect(Collectors.toList());
            Map<String, String> typeIdMap = dictDrillTypes.getData().get(0).getDataList().stream().collect(Collectors.toMap(DictData::getId, DictData::getDictLabel));
            // 获取演练类型没有被应用的id
            List<String> lose = dirllTypeList.stream().filter(id -> !drillType.contains(id)).collect(Collectors.toList());
            Integer total = 0;
            // 计算总数
            if (null != drillTypeAnalysis && drillTypeAnalysis.size() > 0) {
                for (Map typeAnalysis : drillTypeAnalysis) {
                    total += Integer.valueOf(typeAnalysis.get("typeNum").toString());
                }
            }
            for (String type : lose) {
                Map typeMap = new HashMap();
                typeMap.put("drillType", type);
                typeMap.put("drillTypeName", typeIdMap.get(type));
                typeMap.put("typeNum", 0);
                drillTypeAnalysis.add(typeMap);
            }
            drillAnalysis.put("total", total);
            Map map = new HashMap();
            map.put("drillAnalysis", drillAnalysis);
            map.put("drillTypeAnalysis", drillTypeAnalysis);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("安全演练统计成功");
            msg.setData(map);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询安全演练统计数据失败");
            return msg;
        }
    }

    @Override
    public MessageBean<Map> safetyTrainAnalysis(SessionFactory factory, String corpCode, String time, Integer year, Integer mouth) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            Calendar calendar = Calendar.getInstance();
            // 判断是否输入了年-月，没有默认当年当月
            if (StringUtils.isEmpty(time)) {
                year = calendar.get(Calendar.YEAR);
                mouth = calendar.get(Calendar.MONTH) + 1;
            } else {
                year = Integer.valueOf(time.split("-")[0]);
                mouth = Integer.valueOf(time.split("-")[1]);
            }
            calendar.set(year, mouth - 1, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.MONTH, 1);
            Date stopDate = calendar.getTime();
            AnalysisMapper mapper = factory.getMapper(AnalysisMapper.class);
            // 获取培训次数和参与人数
            Map trainAnalysis = mapper.getTrainAnalysis(startDate, stopDate, codeList);
            // 获取有考试成绩的数据
            List<Map> trainList = factory.getMapper(AnalysisMapper.class).getTrainScoreAnalysis(startDate, stopDate, codeList);
            // 获取考试成绩合格的数据
            List<Map> passList = trainList.stream().filter(map -> ("y").equalsIgnoreCase(map.get("is_pass").toString())).collect(Collectors.toList());
            // 计算合格率
            if (null != trainList && trainList.size() > 0) {
                BigDecimal rate = new BigDecimal(passList.size()).divide(new BigDecimal(trainList.size()), 4, BigDecimal.ROUND_HALF_UP);
                // 将完成率转换成百分比
                NumberFormat percent = NumberFormat.getPercentInstance();
                percent.setMaximumFractionDigits(0);
                trainAnalysis.put("passRate", percent.format(rate));
            } else {
                trainAnalysis.put("passRate", "100%");
            }
            trainAnalysis.put("trainScoreCount", trainList.size());
            trainAnalysis.put("trainNoPassCount", trainList.size() - passList.size());
            trainAnalysis.put("trainPassCount", passList.size());
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("安全培训统计成功");
            msg.setData(trainAnalysis);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("查询安全培训统计数据失败");
            return msg;
        }
    }

    @Override
    public MessageBean<Map> getHazarsSourceAnalysis(SessionFactory factory, String corpCode) {
        MessageBean<Map> msg = new MessageBean<>();
        try {
            if (StringUtils.isEmpty(corpCode)) {
                corpCode = corp;
            }
            Map map = new HashMap();
            //查询当前公司下的所有网格（包括网格和部门）
            List<String> codeList = nodeService.getChildCodeList(corpCode);
            if (null == codeList) {
                codeList = new ArrayList<>();
            }
            if (!codeList.contains(corpCode)) {
                codeList.add(corpCode);
            }
            AnalysisMapper mapper = factory.getMapper(AnalysisMapper.class);
            //查风险统计,一般风险，较低风险，较大风险，重大风险
            Map analysis = mapper.queryCountRiskHazardSourceByGrid(codeList);
            setHazardSourceMap(analysis);
            map.put("analysis", analysis);
            //查风险类型数据
            List<Map> hazardTypeList = mapper.getHazardType(codeList);
            if (null != hazardTypeList && hazardTypeList.size() > 0) {
                for (Map hazardTypeMap : hazardTypeList) {
                    String hazardSourceIds = hazardTypeMap.get("hazardSourceIds").toString();
                    List<String> hazardSourceIdList = Arrays.asList(hazardSourceIds.split(","));
                    // 查询类型下的风险数据
                    if (null != hazardSourceIdList && hazardSourceIdList.size() > 0) {
                        Map countHazardType = mapper.getCountRiskHazardSourceByHazardSourceId(hazardSourceIdList);
                        setHazardSourceMap(countHazardType);
                        hazardTypeMap.put("hazardTypeCount", countHazardType);
                    }
                    hazardTypeMap.remove("hazardSourceIds");
                }
            }
            map.put("list", hazardTypeList);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("危险源统计成功");
            msg.setData(map);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("危险源统计数据失败");
            return msg;
        }
    }


    /**
     * 获取集团下所有坐标点，并返回树形结构
     *
     * @param user
     * @return
     */
    @Override
    public MessageBean<PointManagement> tree(StaffBean user) {
        MessageBean<PointManagement> msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, PointManagement.class);
        try (SessionFactory factory = new SessionFactory()) {
            List<DepartmentTreeBean> deptList = null;
            MessageBean<?> depttreeMsg = null;
            // 获取所有坐标点
            List<PointManagement> list = factory.getMapper(PointManagementMapper.class).getAll();
            List<String> pointCorpCodeList = list.stream().map(PointManagement::getCorpCode).collect(Collectors.toList());
            Map<String, PointManagement> pointManagementMap = list.stream().collect(Collectors.toMap(PointManagement::getCorpCode, point -> point, (o1, o2) -> o2));
            // 获取集团单位坐标点
            PointManagement pointManagement = null;
            List<PointManagement> pointManagementList = list.stream().filter(bean -> corp.equals(bean.getCorpCode())).collect(Collectors.toList());
            if (null != pointManagementList && pointManagementList.size() > 0) {
                pointManagement = pointManagementList.get(0);
            }
            if (null != pointManagement) {
                //获取集团单位的直接下属公司
                depttreeMsg = util.depttree(corp, 0);
                if (null != depttreeMsg && depttreeMsg.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                    deptList = (List<DepartmentTreeBean>) depttreeMsg.getData();
                }
                if (null != deptList && deptList.size() > 0) {
                    deptList = deptList.stream().filter(bean -> (bean.getDeptType() & 16) == 16).filter(bean -> !corp.equals(bean.getDepartmentCode())).collect(Collectors.toList());
                    List<PointManagement> result = new ArrayList<>();
                    deptList.forEach(d -> {
                        if (pointCorpCodeList.contains(d.getDepartmentCode())) {
                            PointManagement point = pointManagementMap.get(d.getDepartmentCode());
                            point.setName(d.getName());
                            result.add(point);
                        } else {
                            PointManagement point = new PointManagement();
                            point.setCorpCode(d.getDepartmentCode());
                            point.setName(d.getName());
                            result.add(point);
                        }
                    });
                    if (null != result && result.size() > 0) {
                        result.forEach(management -> {
                            MessageBean<?> messageBean = util.depttree(management.getCorpCode(), 1);
                            if (null != messageBean && messageBean.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                                List<DepartmentTreeBean> departmentTreeBeanList = (List<DepartmentTreeBean>) messageBean.getData();
                                if (null != departmentTreeBeanList && departmentTreeBeanList.size() > 0) {
                                    departmentTreeBeanList = departmentTreeBeanList.stream().filter(bean -> (bean.getDeptType() & 16) == 16).filter(bean -> !management.getCorpCode().equals(bean.getDepartmentCode())).collect(Collectors.toList());
                                    List<PointManagement> managementList = new ArrayList<>();
                                    departmentTreeBeanList.forEach(d -> {
                                        if (pointCorpCodeList.contains(d.getDepartmentCode())) {
                                            PointManagement point = pointManagementMap.get(d.getDepartmentCode());
                                            point.setName(d.getName());
                                            managementList.add(point);
                                        } else {
                                            PointManagement point = new PointManagement();
                                            point.setCorpCode(d.getDepartmentCode());
                                            point.setName(d.getName());
                                            managementList.add(point);
                                        }
                                    });
                                    if (null != managementList && managementList.size() > 0) {
                                        management.setChild(1);
                                        management.setChildList(managementList);
                                    }
                                }
                            }
                        });
                        pointManagement.setChild(1);
                        pointManagement.setChildList(result);
                    }
                }
            }
            msg.setData(pointManagement);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_FAIL);
            return msg;
        }
    }


    public void setHazardSourceMap(Map map) {
        if (null == map) {
            map.put("lowRisk", 0);
            map.put("normalRisk", 0);
            map.put("greaterRisk", 0);
            map.put("majorRisk", 0);
            map.put("total", 0);
        } else {
            Integer total = Integer.valueOf(map.get("lowRisk").toString()) + Integer.valueOf(map.get("normalRisk").toString()) + Integer.valueOf(map.get("greaterRisk").toString()) + Integer.valueOf(map.get("majorRisk").toString());
            map.put("total", total);
        }
    }


    private void setMap() {
        try (SessionFactory factory = new SessionFactory()) {
            IndicationItemsMapper mapper = factory.getMapper(IndicationItemsMapper.class);
            String nomarlDangerCount = mapper.matchIndicationItems("隐患分级", "一般隐患") == null ? null :
                    mapper.matchIndicationItems("隐患分级", "一般隐患").getId();
            if (StringUtils.isNotEmpty(nomarlDangerCount)) {
                mapDict.put("nomarlDangerCount", nomarlDangerCount);
            }
            String importantDangerCont = mapper.matchIndicationItems("隐患分级", "重大隐患") == null ? null :
                    mapper.matchIndicationItems("隐患分级", "重大隐患").getId();
            if (StringUtils.isNotEmpty(importantDangerCont)) {
                mapDict.put("importantDangerCont", importantDangerCont);
            }
            String managerDangetCount = mapper.matchIndicationItems("隐患分类", "管理缺陷") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "管理缺陷").getId();
            if (StringUtils.isNotEmpty(managerDangetCount)) {
                mapDict.put("managerDangetCount", managerDangetCount);
            }
            String deviceDangerCount = mapper.matchIndicationItems("隐患分类", "设备设施隐患") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "设备设施隐患").getId();
            if (StringUtils.isNotEmpty(deviceDangerCount)) {
                mapDict.put("deviceDangerCount", deviceDangerCount);
            }
            String meterialDangerCount = mapper.matchIndicationItems("隐患分类", "物料隐患") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "物料隐患").getId();
            if (StringUtils.isNotEmpty(meterialDangerCount)) {
                mapDict.put("meterialDangerCount", meterialDangerCount);
            }
            String personDangerCount = mapper.matchIndicationItems("隐患分类", "人的不安全行为") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "人的不安全行为").getId();
            if (StringUtils.isNotEmpty(personDangerCount)) {
                mapDict.put("personDangerCount", personDangerCount);
            }
            String goodsDangerCount = mapper.matchIndicationItems("隐患分类", "物的不安全状态") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "物的不安全状态").getId();
            if (StringUtils.isNotEmpty(goodsDangerCount)) {
                mapDict.put("goodsDangerCount", goodsDangerCount);
            }
            String enviropmentDangerCount = mapper.matchIndicationItems("隐患分类", "环境因素") == null ? null :
                    mapper.matchIndicationItems("隐患分类", "环境因素").getId();
            if (StringUtils.isNotEmpty(enviropmentDangerCount)) {
                mapDict.put("enviropmentDangerCount", enviropmentDangerCount);
            }
            String unreformCount = mapper.matchIndicationItems("隐患整改状态", "未整改") == null ? null :
                    mapper.matchIndicationItems("隐患整改状态", "未整改").getId();
            if (StringUtils.isNotEmpty(unreformCount)) {
                mapDict.put("unreformCount", unreformCount);
            }

            String reformingCount = mapper.matchIndicationItems("隐患整改状态", "整改中") == null ? null :
                    mapper.matchIndicationItems("隐患整改状态", "整改中").getId();
            if (StringUtils.isNotEmpty(reformingCount)) {
                mapDict.put("reformingCount", reformingCount);
            }
            String alreadyReformCount1 = mapper.matchIndicationItems("隐患整改状态", "已整改") == null ? null :
                    mapper.matchIndicationItems("隐患整改状态", "已整改").getId();
            if (StringUtils.isNotEmpty(alreadyReformCount1)) {
                mapDict.put("alreadyReformCount1", alreadyReformCount1);
            }
            String refuseReformCount = mapper.matchIndicationItems("隐患整改状态", "整改驳回") == null ? null :
                    mapper.matchIndicationItems("隐患整改状态", "整改驳回").getId();
            if (StringUtils.isNotEmpty(refuseReformCount)) {
                mapDict.put("refuseReformCount", refuseReformCount);
            }
            String majorHazardSource = mapper.matchIndicationItems("危险源级别", "重大") == null ? null :
                    mapper.matchIndicationItems("危险源级别", "重大").getId();
            if (StringUtils.isNotEmpty(majorHazardSource)) {
                mapDict.put("majorHazardSource", majorHazardSource);
            }
            String groupClass = mapper.matchIndicationItems("检查层级", "班组级") == null ? null :
                    mapper.matchIndicationItems("检查层级", "班组级").getId();
            if (StringUtils.isNotEmpty(groupClass)) {
                mapDict.put("groupClass", groupClass);
            }
            String plateClass = mapper.matchIndicationItems("检查层级", "班组级") == null ? null :
                    mapper.matchIndicationItems("检查层级", "班组级").getId();
            if (StringUtils.isNotEmpty(plateClass)) {
                mapDict.put("plateClass", plateClass);
            }
            String departmnetClass = mapper.matchIndicationItems("检查层级", "班组级") == null ? null :
                    mapper.matchIndicationItems("检查层级", "班组级").getId();
            if (StringUtils.isNotEmpty(departmnetClass)) {
                mapDict.put("departmnetClass", departmnetClass);
            }
            String corpClass = mapper.matchIndicationItems("检查层级", "班组级") == null ? null :
                    mapper.matchIndicationItems("检查层级", "班组级").getId();
            if (StringUtils.isNotEmpty(corpClass)) {
                mapDict.put("corpClass", corpClass);
            }
        }
    }
}
